package com.bnzj.cloud.business.core.web;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import javax.validation.Valid;

import com.bnzj.cloud.business.core.persistence.entity.SysRoleResource;
import com.bnzj.cloud.business.core.service.SysResourceService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.bnzj.cloud.business.core.constant.ManagerConstant;
import com.bnzj.cloud.business.core.persistence.entity.SysResource;
import com.bnzj.core.action.ActionType;
import com.bnzj.core.action.annotation.Action;
import com.bnzj.core.exception.BusinessException;
import com.bnzj.core.persistence.util.EntityUtils;
import com.bnzj.core.rest.CurrentUserService;
import com.bnzj.core.rest.ResponseResult;
import com.bnzj.core.rest.ResultCode;
import com.bnzj.core.rest.UserInfo;
import com.bnzj.core.util.BeanUtils;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;

/**
 * @author Barry
 * @createDate 2020/2/17
 * @description
 */
@Tag(name = "资源菜单", description = "资源菜单")
@RestController
@RequestMapping("/system/resource")
public class SysResourceController {

    @Autowired
    private CurrentUserService gatewayCurrentUserService;

    @Autowired
    private SysResourceService sysResourceService;


    @Operation(summary = "根据工号和url查找菜单", description = "参数请放在body中，根据工号和url查找菜单", method = "POST",
            parameters = {
                    @Parameter(in = ParameterIn.QUERY, name = "account", description = "工号", allowEmptyValue = true, allowReserved = true, schema = @Schema(implementation = String.class, description = "工号")),
                    @Parameter(name = "url", description = "路径", allowEmptyValue = true, allowReserved = true, schema = @Schema(implementation = String.class, description = "路径"))
            })
    @PostMapping("/url/user")
    public ResponseResult<List<SysResource>> findByUserAndUrl(@RequestBody Map<String, Object> params) {
        if (ObjectUtils.isEmpty(params.get("account")) | ObjectUtils.isEmpty(params.get("url"))) {
            throw new BusinessException(ResultCode.getResultCode(ResultCode.BAD_REQUEST));
        }
        List<SysResource> resourceList = sysResourceService.findByUserAndUrl(params.get("account").toString(), params.get("url").toString());
        if (CollectionUtils.isEmpty(resourceList)) {
            throw new BusinessException(ResultCode.getResultCode(ResultCode.RESOURCE_NOT_EXIST));
        }
        return ResponseResult.success(resourceList);
    }


    @Operation(summary = "根据工号和url查询所有子菜单", description = "参数请放在body中，根据工号和url查找菜单", method = "POST",
            parameters = {
                    @Parameter(in = ParameterIn.QUERY, name = "account", description = "工号", allowEmptyValue = true, allowReserved = true, schema = @Schema(implementation = String.class, description = "工号")),
                    @Parameter(name = "url", description = "路径", allowEmptyValue = true, allowReserved = true, schema = @Schema(implementation = String.class, description = "路径"))
            })
    @PostMapping("/children")
    public ResponseResult<List<SysResource>> findChildByUserAndUrl(@RequestBody Map<String, Object> params) {
        if (ObjectUtils.isEmpty(params.get("account")) | ObjectUtils.isEmpty(params.get("url"))) {
            throw new BusinessException(ResultCode.getResultCode(ResultCode.BAD_REQUEST));
        }
        List<SysResource> resourceList = sysResourceService.findChildByUserAndUrl(params.get("account").toString(), params.get("url").toString());
        if (CollectionUtils.isEmpty(resourceList)) {
            throw new BusinessException(ResultCode.getResultCode(ResultCode.RESOURCE_NOT_EXIST));
        }
        return ResponseResult.success(resourceList);
    }


    @Operation(summary = "根据Pid和url查询pid下菜单", description = "参数请放在body中，根据pid和url查找菜单", method = "POST",
            parameters = {
                    @Parameter(in = ParameterIn.QUERY, name = "pid", description = "父id", allowEmptyValue = true, allowReserved = true, schema = @Schema(implementation = String.class, description = "工号")),
                    @Parameter(name = "url", description = "请求路径", allowEmptyValue = true, allowReserved = true, schema = @Schema(implementation = String.class, description = "路径"))
            })
    @PostMapping("/parent/url")
    public ResponseResult<SysResource> findByPidAndUrl(@RequestBody Map<String, Object> params) {
        if (ObjectUtils.isEmpty(params.get("pid")) | ObjectUtils.isEmpty(params.get("url"))) {
            throw new BusinessException(ResultCode.getResultCode(ResultCode.BAD_REQUEST));
        }
        Optional<SysResource> sysResourceObj = sysResourceService.findByPidAndUrl(Long.valueOf(params.get("account").toString()), params.get("url").toString());
        if (!sysResourceObj.isPresent()) {
            throw new BusinessException(ResultCode.getResultCode(ResultCode.RESOURCE_NOT_EXIST));
        }
        return ResponseResult.success(sysResourceObj.get());
    }


    @Operation(summary = "根据id查询")
    @GetMapping("/one/{id}")
    public ResponseResult<?> getById(@Parameter(in = ParameterIn.PATH, name = "id", description = "主键", required = true) @PathVariable("id") Long id) {
        Optional<SysResource> optional = sysResourceService.findById(id);
        return ResponseResult.success(optional.orElse(null));
    }


    @Operation(summary = "保存")
    @Action(descriprion = "资源保存",moduleName = "资源",operateType = ActionType.ADD_DATA)
    @PostMapping("/save")
    public ResponseResult<?> addResource(@RequestBody
                                         @Valid SysResource sysResource) {
        if (ManagerConstant.ResourceType.getEnumType(sysResource.getType()) == ManagerConstant.ResourceType.UNKNOWN) {
            throw new BusinessException(ResultCode.getResultCode(ResultCode.RESOURCE_NOT_EXIST));
        }
        UserInfo userInfo = gatewayCurrentUserService.getUserInfo();
        EntityUtils.saveBefore(sysResource, userInfo.getAccount(), userInfo.getName());
        sysResourceService.saveResource(sysResource);
        return ResponseResult.success();
    }

    @Operation(summary = "保存资源new")
    @Action(descriprion = "资源保存new",moduleName = "资源",operateType = ActionType.ADD_DATA)
    @PostMapping("/savenew")
    public ResponseResult<?> addResourceNew(@RequestBody
                                         @Valid SysResource sysResource) {
        if (ManagerConstant.ResourceType.getEnumType(sysResource.getType()) == ManagerConstant.ResourceType.UNKNOWN) {
            throw new BusinessException(ResultCode.getResultCode(ResultCode.RESOURCE_NOT_EXIST));
        }
        UserInfo userInfo = gatewayCurrentUserService.getUserInfo();
        EntityUtils.saveBefore(sysResource, userInfo.getAccount(), userInfo.getName());
        sysResourceService.saveResource(sysResource);
        return ResponseResult.success();
    }


    @Operation(summary = "更新")
    @Action(descriprion = "资源更新",moduleName = "资源",operateType = ActionType.UPDATE_DATA)
    @PostMapping("/update")
    public ResponseResult<?> updateResource(@RequestBody SysResource sysResource) {
        if (ObjectUtils.isEmpty(sysResource.getId())) {
            throw new BusinessException(ResultCode.getResultCode(ResultCode.RESOURCE_NOT_EXIST));
        }
        if (ManagerConstant.ResourceType.getEnumType(sysResource.getType()) == ManagerConstant.ResourceType.UNKNOWN) {
            throw new BusinessException(ResultCode.getResultCode(ResultCode.RESOURCE_NOT_EXIST));
        }
        UserInfo userInfo = gatewayCurrentUserService.getUserInfo();
        Optional<SysResource> sysResourceOpt = sysResourceService.findById(sysResource.getId());
        if (!sysResourceOpt.isPresent()) {
            throw new BusinessException(ResultCode.getResultCode(ResultCode.BAD_REQUEST));
        }
        SysResource sysResourceDb = sysResourceOpt.get();
        BeanUtils.copyProperties(sysResource, sysResourceDb);
        EntityUtils.saveBefore(sysResourceDb, userInfo.getAccount(), userInfo.getName());
        sysResourceService.save(sysResourceDb);
        return ResponseResult.success();
    }

    @Operation(summary = "授权")
    @Action(descriprion = "授权",moduleName = "资源",operateType = ActionType.ADD_DATA)
    @PostMapping("/auth")
    public ResponseResult<?> auth(@RequestBody Map<String, String> map) {
        String roleId = map.get("roleId");
        String resourceIds = map.get("resourceIds");

        if (ObjectUtils.isEmpty(roleId)) {
            throw new BusinessException("角色id不能为空", ResultCode.BAD_REQUEST);
        }
        if (ObjectUtils.isEmpty(resourceIds)) {
            throw new BusinessException("资源ids不能为空", ResultCode.BAD_REQUEST);
        }

        UserInfo userInfo = gatewayCurrentUserService.getUserInfo();
        sysResourceService.saveRoleResource(roleId, resourceIds, userInfo.getAccount(), userInfo.getName());
        return ResponseResult.success();
    }

    /**
     * @param
     * @return com.bnzj.core.rest.ResponseResult
     * @depict 获取当前用户权限的所有菜单
     * @auth Barry
     * @createDate 2020/2/17
     * @updateAuthOrOther
     */
    @Operation(summary = "获取当前用户的菜单集合")
    @PostMapping("/menu/current-user")
    public ResponseResult<List<SysResource>> getMenuByCurrentUser() {
        String account = gatewayCurrentUserService.getAccount();
        List<SysResource> menus = new ArrayList<SysResource>();
        //管理员看到所有菜单
        if(account.equals("admin")) {
            menus = sysResourceService.getMenuByCurrentUserAdmin();
        } else {
            menus = sysResourceService.getMenuByCurrentUser(account);
        }
        //List<SysResource> menus = sysResourceService.getMenuByCurrentUser(gatewayCurrentUserService.getAccount());
        return ResponseResult.success(menus);
    }

    /**
     * @param
     * @return com.bnzj.core.rest.ResponseResult
     * @depict 获取所有资源tree
     * @auth Barry
     * @createDate 2020/2/17
     * @updateAuthOrOther
     */
    @Operation(summary = "获取所有资源tree")
    @GetMapping("/menu/tree")
    public ResponseResult<List<SysResource>> getMenuTree() {
        List<SysResource> menus = sysResourceService.getMenuTree();
        return ResponseResult.success(menus);
    }


    @Operation(summary = "获取当前用户所有按钮", description = "获取当前用户所有按钮类型为1的资源")
    @GetMapping("/button/list")
    public ResponseResult<List<SysResource>> getButtonList() {
        String account = gatewayCurrentUserService.getAccount();
        List<SysResource> buttons = new ArrayList<SysResource>();
        //管理员看到所有按钮
        if(account.equals("admin")) {
            buttons = sysResourceService.getCurrentUserButtonAdmin(ManagerConstant.ResourceType.RESOURCE_TYPE_1.getCode());
        } else {
            buttons = sysResourceService.getCurrentUserButton(account, ManagerConstant.ResourceType.RESOURCE_TYPE_1.getCode());
        }
        //List<SysResource> buttons = sysResourceService.getCurrentUserButton(gatewayCurrentUserService.getAccount(), ManagerConstant.ResourceType.RESOURCE_TYPE_1.getCode());
        return ResponseResult.success(buttons);
    }

    /**
     * @param
     * @return com.bnzj.core.rest.ResponseResult
     * @depict 删除菜单以及其子菜单以及关联的用角色权限
     * @auth Barry
     * @createDate 2020/2/17
     * @updateAuthOrOther
     */
   /* @Operation(summary = "删除菜单以及其子菜单以及关联的用角色权限")
    @GetMapping("/delete/{id}")
    public ResponseResult<?> delete(@Parameter(required = true, name = "id", description = "主键", in = ParameterIn.PATH) @PathVariable("id") Long id) {
        sysResourceService.deleteById(id);
        return ResponseResult.success();
    }*/

}
